package com.taldh.algorithm.mutli.thread;

import com.taldh.mutlithread.ThreadA;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;

/**
 * date 2020/5/31
 *
 * @author 袁小黑
 * @version 1.0.0
 **/

public class PrintAbc {

    //评测题目: 无
/** 三个线程，A线程打印A，B线程打印B，C线程打印C，按顺序依次打印10次，
 *输出ABCABCABCABCABCABCABCABCABCABC，超过一种实现方式有加分~
 */
    private int n;

    public PrintAbc(int n) {
        this.n = n;
    }

//    private Semaphore aSemaphore = new Semaphore(1);
//    private Semaphore bSemaphore = new Semaphore(0);
//    private Semaphore cSemaphore = new Semaphore(0);

    private volatile int flag = 0;
    static Thread threadA = null;
    static Thread threadB = null;
    static Thread threadC = null;

    public void printA() throws InterruptedException {

        for (int i = 0; i < n; i++) {
//            if (flag != 0) {
                LockSupport.park(threadA);
//            }
            System.out.print("A");
//            flag = 1;
            LockSupport.unpark(threadB);
        }
    }

    public void printB() throws InterruptedException {

        for (int i = 0; i < n; i++) {
//            if (flag != 1) {
                LockSupport.park(threadB);
//            }
            System.out.print("B");
//            flag = 2;
            LockSupport.unpark(threadC);
        }
    }
    public void printC() throws InterruptedException {

        for (int i = 0; i < n; i++) {
//            if (flag != 2) {
                LockSupport.park(threadC);
//            }
            System.out.print("C");
//            flag = 0;
            LockSupport.unpark(threadA);
        }
    }

    public static void main(String[] args) {
        PrintAbc printAbc = new PrintAbc(10);
        Runnable printA = () -> {
            try {
                printAbc.printA();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        Runnable printB = () -> {
            try {
                printAbc.printB();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        Runnable printC = () -> {
            try {
                printAbc.printC();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        threadA = new Thread(printA);
        threadB = new Thread(printB);
        threadC = new Thread(printC);
        threadA.start();
        threadB.start();
        threadC.start();
        LockSupport.unpark(threadA);
    }

}
